/// `OrderItem` 是一个数据模型类，用于表示一个订单项。
///
/// 这个类是不可变的（immutable），并提供了序列化和反序列化（`toJson`, `fromJson`）
/// 以及对象比较（`==`, `hashCode`）和复制（`copyWith`）的功能。
///
/// - **职责**: 定义订单数据的结构，并提供常用的辅助方法。
/// - **用途**: 在应用中传递订单数据，以及与数据源（如API）进行交互。
class OrderItem {
  /// 订单的唯一标识符。
  final String id;

  /// 订单创建的日期和时间。
  final DateTime date;

  /// 订单金额。
  final double amount;

  /// 订单类型，例如 "dine-in", "take-out" 等。
  final String type;

  /// `OrderItem` 的构造函数。
  OrderItem({
    required this.id,
    required this.date,
    required this.amount,
    required this.type,
  });

  /// 创建一个新的 `OrderItem` 实例，并可以覆盖部分属性。
  ///
  /// 这对于在不修改原始对象的情况下更新订单数据非常有用。
  OrderItem copyWith({
    String? id,
    DateTime? date,
    double? amount,
    String? type,
  }) {
    return OrderItem(
      id: id ?? this.id,
      date: date ?? this.date,
      amount: amount ?? this.amount,
      type: type ?? this.type,
    );
  }

  /// 从 JSON `Map` 创建一个 `OrderItem` 实例。
  ///
  /// 这是反序列化的过程，通常用于从 API 响应中解析数据。
  factory OrderItem.fromJson(Map<String, dynamic> json) {
    return OrderItem(
      id: json['id'] as String,
      date: DateTime.parse(json['date'] as String),
      amount: (json['amount'] as num).toDouble(),
      type: json['type'] as String,
    );
  }

  /// 将 `OrderItem` 实例转换为 JSON `Map`。
  ///
  /// 这是序列化的过程，通常用于向 API 发送数据。
  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'date': date.toIso8601String(),
      'amount': amount,
      'type': type,
    };
  }

  /// 返回对象的字符串表示形式，便于调试。
  @override
  String toString() {
    return 'OrderItem(id: $id, date: $date, amount: $amount, type: $type)';
  }

  /// 比较两个 `OrderItem` 对象是否相等。
  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;

    return other is OrderItem &&
        other.id == id &&
        other.date == date &&
        other.amount == amount &&
        other.type == type;
  }

  /// 返回对象的哈希码，用于在哈希集合（如 `Map`, `Set`）中进行高效查找。
  @override
  int get hashCode {
    return id.hashCode ^ date.hashCode ^ amount.hashCode ^ type.hashCode;
  }
}